LESSON 3
THE VERTICAL BLANK REGISTER
OUTPUT PORT 0AH
Version 3.0

The only RAM in the Bally/Astrocade console is screen RAM. Unfortunately, with this situation, variables, routine flags, data blocks, the Z80 stack area, etc, must be located in the bottom of the screen RAM area plus the extra 16 bytes of scratchpad RAM at 4FF0 thru 4FFFH. The hardware allows this data to be hidden from view by setting a vertical blanking line to the desired height. The NM system description, page 90, provides some additional info on vertical blanking.

The listing below shows the starting address for each of the bottom 12 lines in screen RAM along with the hex value that must be output to the Vertical Blank Register, port 0AH, to hide RAM at that line and below. To reveal ALL screen RAM lines, output CCH to port 0AH. The top 8 lines in the listing below from 4E10 to 4F28H are used by MLM for up to 320 program bytes, using the default program set up.

Line	Screen Line		Hex Value To Output
Num*	Start Hex Adr	To Hide This Line
				And Below

90	4E10				B4
91	4E38				B6
92	4E60				B8
93	4E88				BA
94	4EB0				BC
95	4ED8				BE
96	4F00				C0
97	4F28				C2
	End Of MLM Program Area
98	4F50				C4
99	4F78				C6
100	4FA0				C8
101	4FC8				CA

Screen bottom, output CCH to show ALL screen RAM lines

* The top screen line is labeled as Line 0.

To summarize, the vertical blanking line can be determined for a program application as follows:

VERBL = (102-SCRATCHL)x 2

Where, VERBL is the decimal value to output to the Vert Blnk Reg, Port 0AH.

       SCRATCHL are the number of scratchpad lines that are to be hidden from
	 view.

For example, if a programmer determined only 3 screen RAM scratchpad lines were required to hide the program's Z80 stack area, data blocks, variables and routine flags, then the hex value to output to port 0AH would be:

VERBL = (102-3)x 2 = 198 = C6H

The other option to determine VERBL would be to simply look at the above listing of up to 12 scratchpad lines to find the hex value to output to port 0AH.

EXAMPLE 3-1

Program Description

Use this example to experiment with the Vertical Blank Register.
Set MLM to its standard colors by running the Screen Spec Utility.
To run this utility,

Press the system reset button.
Press the MLM CALL button.
Press the MLM WRITE button 4 times.

Enter the short program below, so you can output a hex value to the Vertical Blank Register, port 0AH.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Example Program 3-1

OUTPUT A HEX VALUE TO VERT BLNK REG, PORT 0AH

4E10H	3E CC		LD A,CCH		A = vert blnk line = CCH
4E12H	D3 0A		OUT (0AH),A		drop vert blnk line to bottom of screen
4E14H	C9		RET 			return to MLM

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

When you run this program, all screen RAM lines will be visible. You will also see the above program on the screen beginning at 4E10H. Note that MLM on a real Bally/Astrocade hardware console does NOT clear (zero) the program area bytes.

Beginner Exercise

This exercise is for a beginner that would like to play with the MLM and actually watch MLM write bytes into the screen RAM area.

Try this. Now that you ran Example Program 3-1 and the vertical blank line has been dropped to the very bottom of the screen RAM, you can now fill the MLM programming area with some alternating colors horizontally. Begin with the RAM address 4E15H, which is the byte following the above program's RET instruction at 4E14H. Manually using MLM, write pixel color 55 (white) bytes across the entire horizontal line and stop at the very end of the line. Do this by entering 4E15, then press the ADR button. Enter 55, then press the WRITE button. You can visually see each byte written changing this line to the pixel color white every time you press the WRITE button. Stop writing bytes at the end of this line. If you accidentally start writing white bytes into the next horizontal RAM line, that's okay.

Now, you can continue writing bytes manually or you can run the next Example Program 3-2 below which will fill the remaining 7 horizontal program area lines for you with alternating colors red and green.

If you want to continue manually, fill in the remaining 7 programming area lines beginning on the 2nd line at 4E38H, alternating with the pixel color AA (red) for one line and then the pixel color FF (green) for the next line. Remember, there are 40 bytes per line.

Note that while watching the screen, when you write the last byte on a line, you do NOT have to enter the screen address for the next line. Simply change the pixel color (FF or AA) and continue pressing the WRITE button. MLM automatically increments to the next RAM address after each write. If you make a mistake, use the listing above to look up the start address for the line you want to correct. You can also use the MLM LIST command to determine which address has the wrong pixel color byte and then correct the mistake. If only a few bytes are the wrong pixel color, you can let that color variation be as is. You are just alternating the program lines with red and green colors because you are going to experiment with the vertical blanking line. The alternating colors will tell you precisely where that blanking line is located. When you are finished filling the 7 MLM programming lines with red and green, you're ready to start experimenting.

So,when you're finished, you should see in the MLM programming area:

Red in the 2nd,4th,6th and 8th lines,
Green in the 3rd,5th and 7th lines.

Now, change the hex byte at 4E11H from CC to B4, then CALL the Example Program 3-1. All RAM lines beginning with the first program line at 4E10H and below should now be hidden from view.

Using the listing above again, now output B6H to the Vertical Blank Register, port 0AH, by changing the byte at 4E11H to B6, then CALL the program again. RAM line 90 should now be visible. This is the line with the MLM program in it.

Continue going down the above list, increasing the hex value to B8,BA,BC,BE, etc at address 4E11H, calling the program after each change. Note that every time you increase the hex value by 2 and output it to the port 0AH, the blanking line drops one screen RAM line.

Example 3-2

Program Description

This example introduces some new Z80 instructions for the beginner.

The example also shows how to use ML to alternate the writing (filling) of red and green colors in the program lines within the MLM program area, beginning at screen RAM address 4E38H, instead of manually writing the bytes as described in the above beginner exercise.

This example however, will change the line locations of the red and green colors. Now, red will be written in the 3rd,5th and 7th lines and green will be written in the 2nd,4th,6th and 8th lines.

Run this example immediately after the beginner exercise above, so you can see the 7 horizontal programming lines change color locations.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Example Program 3-2

Fill 7 MLM programming lines, beginning at 4E38H,
with alternating colors green and red.
There are 40 bytes per line.

OUTPUT A HEX VALUE TO VERT BLNK REG, PORT 0AH

PGM	4E10H 3E CC		LD A,CCH		A= vert blnk line value = CCH.
		D3 0A		OUT (0AH),A		drop vert blnk line, bottom of scrn.
							show all RAM lines.

FILL 7 MLM PGM AREA LINES BEGINNING WITH THE COLOR GREEN

		21 38 4E	LD HL,4E38H		point HL at 2nd pgm line number 91.
							HL = start adr, 2nd line.
	4E17H 06 07		LD B,7		B = scrn line loop ctr = 7 to
							fill 7 pgm lines total.
PGM1	4E19H 50		LD D,B		save loop ctr in D.

		3E FF		LD A,FFH		A = pixel clr grn.
		CB 40		BIT 0,B		[if loop ctr is odd,
		20 02	      JR NZ,PGM2		use clr grn FFH and
							jmp forward 2 bytes.
							see note 1 below.
	4E20H	3E AA 	LD A,AAH		otherwise, ctr is even,
							use clr red AAH.]
PGM2		06 28		LD B,28H		B = bytes/line = 40 = 28H.
PGM3		77		LD (HL),A		fill RAM byte with the color.
		23		INC HL		point to next RAM byte.
		10 FC		DJNZ PGM3		loop back to write the next byte
							in the line?
							If so, jmp back 4 bytes.
						 	2's complement to convert to neg.
							See note 2 below.
	4E28H	42		LD B,D		put line loop ctr back in B.
		10 EE		DJNZ,PGM1		decrement loop ctr B.
							loop back to get next clr for next
							line to fill? If so,
							jump back 18 bytes (B is not 0).
							Use 2's complement to get EEH.
							See note 3 below.
	4E2BH	C9		RET			return to MLM.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Note 1
Check bit 0 in loop counter (ctr). If it is set (not zero), the counter number is odd, so use color green and jump 2 bytes to PGM2. If bit 0 is zero (reset), the ctr number is even, so continue and use color red.

Note 2
How to determine the hex value (the jump code) for a relative jump.

The jump code follows the instruction's opcode. Assembly language software will compute this jump code automatically. But, when using the MLM, you have to supply the jump code.

The Z80 must fetch an instruction from memory before it can execute it. After the instruction is fetched, the Z80 program counter (PC) is incremented and points to the following instruction. THAT is the address that you begin counting the bytes to jump to. If the jump is backward (negative, you are looping back to an address), then perform a 2's complement on that backward byte count and use that conversion as the hex value (the byte code) that follows the instruction's opcode.

Jump back 4 bytes
from address 4E28H.	      0000 0100
Complement that byte count.	1111 1011
Add 1 to the complement.      _______+1
The sum is the hex byte code  1111 1100
to use and place after the     F    C
jump relative opcode, which
is in this case 10H. The jump code is FCH. So, the 2 byte coding for this DJNZ,PGM1 instruction is 10 FC. 

The range for any relative jump is
-128 to +127 bytes where,

-128 is a backward jump up to 128 bytes maximum.
You must perform a 2's complement on the backward jump byte count.
This conversion to a negative number is the hex byte code that should follow the relative jump's opcode.

+127 is a forward jump up to 127 bytes maximum.

The following are examples of hex jump byte codes that follow a relative jump opcode:

-128	1000 0000 = 80H
-127 	1000 0001 = 81H
	    .
  	    .
	    .
-2	1111 1110 = FEH
-1   	1111 1111 = FFH
 0	0000 0000 = 00H
+1	0000 0001 = 01H
+2    0000 0010 = 02H
	    .
	    .
	    .
+126  0111 1110 = 7EH
+127	0111 1111 = 7FH

The left most bit 7 determines if the hex (or binary) number is negative or positive. This bit 7 is called the sign bit.
Bit 7=1, the number is negative.
Bit 7=0, the number is positive.

Note 3
Determine the jump code as follows:

Jump back 18 bytes
from address 4E2BH.		0001 0010
Complement that byte count.	1110 1101
Add 1 to the complement.	_______+1
The sum is the jump code.	1110 1110
					  E    E

Use hex byte EE as the jump code following the DJNZ opcode 10H.

Beginner Exercise

If you didn't experiment with the vertical blanking line described in the Example Program 3-1 exercise, you can do that now. See the last 3 paragraphs in that exercise.

End of the Lesson 3 document
The Vertical Blank Register
MCM Design
July 2019